home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * © Copyright 1994, Apple Computer, Inc.
- *
- * by Rob Glanville
- *
- * 30 Mar 94
- *
- * PCITest.c - tests for PCI compliance
- *
- * PCITest.c is a simple test for PCI configuration space compliance testing. It writes and reads
- * various config space registers and checks them for expected values according to the current
- * PCI specification. There are a few routines that are hardware dependent and those must be
- * supplied by the user. To use the test, simply add in the hardware specific code, compile
- * it on your target machine, and run it as an application.
- *
- * This is a first pass of the test suite.
- */
-
- #include <stdio.h>
-
-
- #define UInt8 unsigned char
- #define UInt16 unsigned short
- #define UInt32 unsigned long
- #define PInt8 *(UInt8 *) /* Used for physical address casting */
- #define PInt16 *(UInt16 *) /* Used for physical address casting */
- #define PInt32 *(UInt32 *) /* Used for physical address casting */
- #define True 0xffffffff
- #define False 0x00000000
- #define Null False /* Nothing but trouble */
-
- /* Configuration space register offsets */
- #define PCI_VendorID 0x0000
- #define PCI_DeviceID 0x0002
- #define PCI_Command 0x0004
- #define PCI_Status 0x0006
- #define PCI_RevisionID 0x0008
- #define PCI_ClassCode 0x0009
- #define PCI_CacheLineSize 0x000c
- #define PCI_LatencyTimer 0x000d
- #define PCI_HeaderType 0x000e
- #define PCI_BIST 0x000f
- #define PCI_BaseAddress0 0x0010
- #define PCI_BaseAddress1 0x0014
- #define PCI_BaseAddress2 0x0018
- #define PCI_BaseAddress3 0x001c
- #define PCI_BaseAddress4 0x0020
- #define PCI_BaseAddress5 0x0024
- #define PCI_Reserved1 0x0028
- #define PCI_Reserved2 0x002c
- #define PCI_ExpansionROM 0x0030
- #define PCI_Reserved3 0x0034
- #define PCI_Reserved4 0x0038
- #define PCI_InterruptLine 0x003c
- #define PCI_InterruptPin 0x003d
- #define PCI_Min_Gnt 0x003e
- #define PCI_Max_Lat 0x003f
-
- UInt8 Data8;
- UInt16 Data16;
- UInt32 Data32;
-
- extern void printstr(const char *);
- extern void outchar(UInt8);
- extern void byteout(UInt8);
- extern void wordout(UInt16);
- extern void longout(UInt32);
- extern void crlf();
-
- /*
- The following external routines are localized hardware dependent
- abstraction layers that provide access to physical or simulated hardware
- */
- extern UInt8 GetPresentsBits(); /* Returns the two presents bits in bits 0 and 1 of byte */
-
- /* Access to PCI configuration space is hardware dependent */
- extern UInt8 Read8_Config (UInt32 RegisterOffset);
- extern void Write8_Config (UInt32 RegisterOffset,UInt8 Data);
- extern UInt16 Read16_Config (UInt32 RegisterOffset);
- extern void Write16_Config(UInt32 RegisterOffset,UInt16 Data);
- extern UInt32 Read32_Config (UInt32 RegisterOffset);
- extern void Write32_Config(UInt32 RegisterOffset,UInt32 Data);
-
- /**************************************** Utilities **************************************/
-
- void PutPass() {
- printf(" passed\n");
- }
-
- void PutFail() {
- printf(" #####> FAILED <#####\n");
- }
-
- void PutSkip() {
- printf(" * skipped *\n");
- }
-
- #define watt25 0x01
- #define watt15 0x02
- #define watt7_5 0x00
-
- /*
- Get the two presents bits from external hardware interface code
- for the unit under test
- */
- UInt8 UnitUnderTestPresent() {
- UInt8 presentbits;
- presentbits = GetPresentsBits();
- if ((presentbits & 0x03) != 0x03) {
- printf("Presents bits = %02x for ",presentbits);
- if (presentbits == watt25) printf("25 watts");
- else if (presentbits == watt15) printf("15 watts");
- else printf("7.5 watts\n");
- return(True);
- }
- else {
- printf("** No card was found\n");
- return(False);
- }
- }
-
- void DisplayConfiguration() {
- Data32 = Read32_Config(PCI_VendorID); /* Read the ID registers */
- printf("Vendor ID = %04x\n",(Data32 & 0x0000ffff));
- printf("Device ID = %04x\n",(Data32 >> 16) & 0x0000ffff);
- Data32 = Read32_Config(PCI_Command); /* Read the command and status registers */
- printf("Command = %04x\n",(Data32 & 0x0000ffff));
- printf("Status = %04x\n",(Data32 >> 16) & 0x0000ffff);
- Data32 = Read32_Config(PCI_RevisionID); /* Read the Revision registers */
- printf("Base class = %02x, Sub-class = %02x, Interface = %02x\n",(Data32 >> 24) & 0x00000ff,(Data32 >> 16) & 0x00000ff,(Data32 >> 8) & 0x00000ff);
- printf("Revision = %02x\n",(Data32 & 0x00000ff));
- Data32 = Read32_Config(PCI_CacheLineSize); /* Read the registers */
- printf("BIST = %02x\n",(Data32 >> 24) & 0x00000ff);
- printf("Header type = %02x\n",(Data32 >> 16) & 0x00000ff);
- printf("Latency = %02x\n",(Data32 >> 8) & 0x00000ff);
- printf("Cache line size = %02x\n",(Data32 & 0x00000ff));
- Data32 = Read32_Config(PCI_BaseAddress0); /* Read the base address registers */
- printf("Base addr 0 = %08x\n",(Data32));
- Data32 = Read32_Config(PCI_BaseAddress1); /* Read the base address registers */
- printf("Base addr 1 = %08x\n",(Data32));
- Data32 = Read32_Config(PCI_BaseAddress2); /* Read the base address registers */
- printf("Base addr 2 = %08x\n",(Data32));
- Data32 = Read32_Config(PCI_BaseAddress3); /* Read the base address registers */
- printf("Base addr 3 = %08x\n",(Data32));
- Data32 = Read32_Config(PCI_BaseAddress4); /* Read the base address registers */
- printf("Base addr 4 = %08x\n",(Data32));
- Data32 = Read32_Config(PCI_BaseAddress5); /* Read the base address registers */
- printf("Base addr 5 = %08x\n",(Data32));
- Data32 = Read32_Config(PCI_ExpansionROM); /* Read the expansion ROM address register */
- printf("ROM base = %08x\n",(Data32));
- Data32 = Read32_Config(PCI_InterruptLine); /* Read registers */
- printf("Max_Lat = %02x\n",(Data32 >> 24) & 0x00000ff);
- printf("Min_Gnt = %02x\n",(Data32 >> 16) & 0x00000ff);
- printf("Interrupt pin = %02x\n",(Data32 >> 8) & 0x00000ff);
- printf("Interrupt line = %02x\n",(Data32 & 0x000000ff));
- }
-
- /* Check that Vendor ID is not equal to 0xffff */
- void VendorIDCheck(){
- printf("Vendor ID Check.......................");
- Data32 = Read16_Config(PCI_VendorID); /* Read the ID register */
- Data16 = Data32 & 0x0000ffff;
- if (Data16 == 0xffff) PutFail();
- else PutPass();
- }
-
- /* Check that Device ID is not equal to 0xffff */
- void DeviceIDCheck(){
- printf("Device ID Check.......................");
- Data32 = Read32_Config(PCI_VendorID); /* Read the ID register */
- Data16 = (Data32 >> 16) & 0x0000ffff;
- if (Data16 == 0xffff) PutFail();
- else PutPass();
- }
-
- void CommandCheck(){
- printf("Command bits Check....................");
- PutSkip();
- }
-
- void StatusCheck(){
- printf("Status bits Check.....................");
- PutSkip();
- }
-
- /* Check for proper class code values */
- void ClassCodeCheck() {
- UInt8 BaseClass,SubClass,ProgramInterface,FailureFlag;
- printf("Class code Check......................");
- FailureFlag = False;
- Data32 = Read32_Config(PCI_RevisionID); /* Read the class code registers */
- BaseClass = (Data32 >> 24) & 0x000000ff;
- SubClass = (Data32 >> 16) & 0x000000ff;
- ProgramInterface = (Data32 >> 8) & 0x000000ff;
- if (BaseClass > 6) FailureFlag = True; /* Only six classes defined so far */
- else if (ProgramInterface > 0) FailureFlag = True; /* Only one program interface */
- else switch(BaseClass) {
- case 0: /* Pre class code devices */
- if (SubClass > 1) FailureFlag = True;
- break;
- case 1:
- if ((SubClass > 3) && (SubClass != 0x80)) FailureFlag = True;
- break;
- case 2:
- if ((SubClass > 2) && (SubClass != 0x80)) FailureFlag = True;
- break;
- case 3:
- if ((SubClass > 1) && (SubClass != 0x80)) FailureFlag = True;
- break;
- case 4:
- if ((SubClass > 1) && (SubClass != 0x80)) FailureFlag = True;
- break;
- case 5:
- if ((SubClass > 1) && (SubClass != 0x80)) FailureFlag = True;
- break;
- case 6:
- if ((SubClass > 5) && (SubClass != 0x80)) FailureFlag = True;
- break;
- }
- if (FailureFlag) PutFail();
- else PutPass();
- }
-
- /* Check that revision register is not equal to 0xff */
- void RevisionCheck(){
- UInt8 Revision;
- printf("Revision Check........................");
- Data32 = Read32_Config(PCI_RevisionID); /* Read the Revision register */
- Revision = Data32 & 0x000000ff;
- if (Revision == 0xff) PutFail();
- else PutPass();
- }
-
- void BISTCheck(){
- UInt8 BIST,FailureFlag;
- UInt32 timer;
- printf("BIST Check............................");
- Data32 = Read32_Config(PCI_CacheLineSize); /* Read the registers */
- FailureFlag = False;
- BIST = (Data32 >> 24) & 0x00000ff;
- if ((BIST & 0x80) == 0x80) { /* Support built in self test, Let's run it */
- Write32_Config(PCI_CacheLineSize,0x40000000); /* Start test */
- timer = 0x80000;while(--timer); /* Delay for test to complete */
- Data32 = Read32_Config(PCI_CacheLineSize); /* Read the registers */
- BIST = (Data32 >> 24) & 0x00000ff;
- if ((BIST & 0x0f) != 0x00) FailureFlag = True; /* Did test fail? */
- }
- if (FailureFlag) PutFail();
- else PutPass();
- }
-
- /* Check that the header type is zero */
- void HeadTypeCheck(){
- UInt8 HeaderType;
- printf("Header type Check.....................");
- Data32 = Read32_Config(PCI_CacheLineSize); /* Read the registers */
- HeaderType = (Data32 >> 16) & 0x00000ff;
- if (HeaderType != 0x00) PutFail();
- else PutPass();
- }
-
- void LatencyTimerCheck(){
- UInt8 Latency;
- printf("Latency timer Check...................");
- Data32 = Read32_Config(PCI_CacheLineSize); /* Read the registers */
- Latency = (Data32 >> 8) & 0x00000ff;
- PutSkip();
- }
-
- void CacheLineCheck(){
- UInt8 CacheLineSize;
- printf("Cache line Check......................");
- Data32 = Read32_Config(PCI_CacheLineSize); /* Read the registers */
- CacheLineSize = (Data32 & 0x00000ff);
- PutSkip();
- }
-
- void BaseRegistersCheck(){
- printf("Base registers Check..................");
- PutSkip();
- }
-
- /* Check that the reserve registers are zero and can't be changed */
- void ReservedRegistersCheck(){
- UInt8 FailureFlag;
- UInt32 ResData1,ResData2,ResData3,ResData4;
- printf("Reserved registers Check..............");
- FailureFlag = False;
- ResData1 = Read32_Config(PCI_Reserved1); /* Read a reserved register */
- ResData2 = Read32_Config(PCI_Reserved2); /* Read a reserved register */
- ResData3 = Read32_Config(PCI_Reserved3); /* Read a reserved register */
- ResData4 = Read32_Config(PCI_Reserved4); /* Read a reserved register */
- if ( (ResData1 != Null) &&
- (ResData2 != Null) &&
- (ResData3 != Null) &&
- (ResData4 != Null) ) FailureFlag = True;
- Write32_Config(PCI_Reserved1,0xffffffff); /* Write a reserved register */
- Write32_Config(PCI_Reserved2,0xffffffff); /* Write a reserved register */
- Write32_Config(PCI_Reserved3,0xffffffff); /* Write a reserved register */
- Write32_Config(PCI_Reserved4,0xffffffff); /* Write a reserved register */
- ResData1 = Read32_Config(PCI_Reserved1); /* Read a reserved register */
- ResData2 = Read32_Config(PCI_Reserved2); /* Read a reserved register */
- ResData3 = Read32_Config(PCI_Reserved3); /* Read a reserved register */
- ResData4 = Read32_Config(PCI_Reserved4); /* Read a reserved register */
- if ( (ResData1 != Null) &&
- (ResData2 != Null) &&
- (ResData3 != Null) &&
- (ResData4 != Null) ) FailureFlag = True;
- if (FailureFlag) PutFail();
- else PutPass();
- }
-
- void ExpansionROMCheck(){
- printf("Expansion ROM Check...................");
- PutSkip();
- }
-
- void InterruptLineCheck(){
- printf("Interrupt line Check..................");
- PutSkip();
- }
-
- void InterruptPinCheck(){
- printf("Interrupt pin Check...................");
- PutSkip();
- }
-
- void MinGrantCheck(){
- UInt8 MinimumGrant;
- float InMicroseconds;
- printf("Minimum grant Check...................");
- MinimumGrant = (Data32 >> 24) & 0x00000ff;
- if (MinimumGrant > 0) {
- InMicroseconds = 0.25 * MinimumGrant;
- printf(" %02.2f microseconds\n",InMicroseconds);
- }
- else printf(" passed, No minimum grant requirements\n");
- }
-
- void MaxLatencyCheck(){
- UInt8 MaximumLatency;
- float InMicroseconds;
- printf("Maximum latency Check.................");
- Data32 = Read32_Config(PCI_InterruptLine); /* Read registers */
- MaximumLatency = (Data32 >> 24) & 0x00000ff;
- if (MaximumLatency > 0) {
- InMicroseconds = 0.25 * MaximumLatency;
- printf(" %02.2f microseconds\n",InMicroseconds);
- }
- else printf(" passed, No latency requirements\n");
- }
-
-
- void PCIComplianceTest(){
- if (UnitUnderTestPresent()) {
- DisplayConfiguration();
- VendorIDCheck();
- DeviceIDCheck();
- CommandCheck();
- StatusCheck();
- ClassCodeCheck();
- RevisionCheck();
- BISTCheck();
- HeadTypeCheck();
- LatencyTimerCheck();
- CacheLineCheck();
- BaseRegistersCheck();
- ReservedRegistersCheck();
- ExpansionROMCheck();
- InterruptLineCheck();
- InterruptPinCheck();
- MinGrantCheck();
- MaxLatencyCheck();
- }
- }
-
- /************************************* End of PCI Tests *************************************/
-